<script>
import {v4 as uuidv4} from 'uuid';

import lodash from 'lodash'

import IconExport from "./icon/IconExport";
import IconFilter from "./icon/IconFilter";
import IconFullscreen from "./icon/IconFullscreen";


export default {

    components: {
        IconExport, IconFilter, IconFullscreen
    },

    // 使用局部注册指令的方式
    directives: {
        // 指令的名称
        resize: {
            // el为绑定的元素，binding为绑定给指令的对象
            bind(el, binding) {
                let width = '', height = '';

                function isReize() {
                    const style = document.defaultView.getComputedStyle(el);
                    if (width !== style.width || height !== style.height) {
                        binding.value();  // 关键
                    }
                    width = style.width;
                    height = style.height;
                }

                el.__vueSetInterval__ = setInterval(isReize, 300);
            },
            unbind(el) {
                clearInterval(el.__vueSetInterval__);
            }
        }
    },
    data() {
        return {

            /**
             * 1.行选中事件,支持选中行时 就默认checkbox选中
             * 2.行选中的时间回调
             * @param record
             * @returns {{on: {click: on.click}}}
             */


            customRow: record => ({
                style: {
                    'background-color': record.rowStyleBackgroundColor ? record.rowStyleBackgroundColor : undefined,
                    'color': record.rowStyleColor ? record.rowStyleColor : undefined
                },
                on: {
                    click: () => {
                    //     if (this.rowSelection) {
                            if (record.isEmpty) {
                                return;
                            }
                    //         if (this.oldSelection.getCheckboxProps) {
                    //             let props = this.oldSelection.getCheckboxProps(record).props
                    //             if(props && props.disabled){
                    //                 return;
                    //             }
                    //         }
                    //         let selectedRowKeys = this.rowSelection.selectedRowKeys;
                    //         const rowKey = this.rowKey;
                    //         let keyValue = record[rowKey];
                    //
                    //         if (typeof (keyValue) == "undefined") {
                    //             console.warn("recorder has no keyValue, can't selected checkbox when row clicked");
                    //             // alert("recorder has no keyValue, can't selected checkbox when row clicked")
                    //             return;
                    //         }
                    //
                    //         let index = selectedRowKeys.findIndex(r => r == keyValue);
                    //         if (this.rowSelection.type == 'checkbox') {
                    //             if (index != -1) {
                    //                 selectedRowKeys.splice(index, 1);
                    //             } else {
                    //                 selectedRowKeys.push(keyValue);
                    //             }
                    //         } else {
                    //             selectedRowKeys.splice(0, 1, keyValue)
                    //
                    //         }
                    //     }
                        if (typeof (this.rowClick) == "function") {
                            this.rowClick(record);
                        }

                    },
                    //双击
                    dblclick: (event) => {
                        if (typeof (this.rowDblClick) == "function") {
                            this.rowDblClick(record);
                        }
                    },
                    //右键
                    contextmenu: (event) => {
                        if (typeof (this.rowContextMenu) == "function") {
                            this.rowContextMenu(record);
                        }
                    },
                    // 鼠标移入行
                    mouseenter: (event) => {
                        if (typeof (this.rowMouseEnter) == "function") {
                            this.rowMouseEnter(record);
                        }
                    },
                    //鼠标移出行
                    mouseleave: (event) => {
                        if (typeof (this.rowMouseLeave) == "function") {
                            this.rowMouseLeave(record);
                        }
                    }
                },
            }),
            //全屏化
            showModel: record => {
                //全屏化时修改pageSize使表格填满页面
                if (this.paginationModel && 'pageSize' in this.paginationModel && this.paginationModel.pageSize) {
                    this.temp = lodash.cloneDeep(this.paginationHasTotal);
                    //表格使用分页查询时,初始化页码为1
                    if ('change' in this.$listeners && 'current' in this.paginationModel) {
                        this.paginationModel.current = 1;
                    }
                    this.paginationModel.pageSize = 17;
                } else {
                    this.paginationModel.pageSize = 17;
                }
                if ('change' in this.$listeners) {
                    this.$listeners.change(this.paginationModel);
                } else if ('current' in this.paginationModel) {
                    delete this.paginationModel.current;
                }
                this.updateDataSource(this.dataSource);
                this.showEditor = true;
            },
            //关闭全屏
            closeModel: record => {
                if (this.paginationModel && 'pageSize' in this.paginationModel) {
                    if (this.temp) {
                        this.paginationModel.pageSize = this.temp.pageSize;
                    } else {
                        this.paginationModel.pageSize = 10;
                    }
                } else {
                    this.paginationModel.pageSize = 10;
                }
                this.updateDataSource(this.dataSource);
                //表格使用分页查询时,还原pagination
                if ('change' in this.$listeners) {
                    this.$listeners.change(this.temp);
                }
                this.showEditor = false;
            },
            showFilterModel: record => {
                this.showFilter = true;
            },
            closeFilterModel: record => {
                this.showFilter = false;
                this.checkedList = this.columnsView.map(e => {
                    return e.dataIndex;
                });
            },
            rowClassName: (record, index) => {
                if (record.isEmpty) {
                    return ''
                }
                let rowClass = index % 2 === 0 ? "rowClassOdd" : "rowClassEven";
                if (record.rowClassName) {
                    return record.rowClassName;
                }
                return rowClass;
            },
            oldSelection: {...this.rowSelection},
            initFlag: false,
            dataList: [],
            showEditor: false,
            showFilter: false,
            temp: '',
            columnsModel: [],
            columnsModelView: [],
            columnsView: [],
            paginationModel: {...this.pagination},
            plainOptions: [],
            indeterminate: true,
            checkAll: false,
            checkedList: [],
            scrollX: '',
            isPagination: true,
        }
    },

    /**
     *
     * 当封装的组件想要封装默写属性时，需要使用props继承过来，不然this.rowKey会报错undefined ，即使父组件传了值过来
     * */
    props: {
        outListFieldPath: {
            type: String,
        },
        queryParam: {
            type: Object,
        },
        exportAuthKey: {
            type: String,
        },
        rowSelection: {
            type: Object,
        },
        selection: {
            type: Boolean,
            default: () => {
                return false
            }
        },
        /**
         *
         * 行单击事件
         * */
        rowClick: {
            type: Function
        },
        /**
         *
         * 行双击事件
         * */
        rowDblClick: {
            type: Function
        },
        /**
         *
         * 行右键事件
         **/
        rowContextMenu: {
            type: Function
        },
        /**
         *
         * 行鼠标移入
         * */
        rowMouseEnter: {
            type: Function
        },

        /**
         *
         * 行鼠标移出
         **/
        rowMouseLeave: {
            type: Function
        },
        /**
         *
         * 当传入的数据没有key值时，自动创建一个
         **/
        dataSource: {
            type: [Array, Function],
            required: true
        },
        rowKey: {
            type: [String, Function],
            default: 'key'
        },
        pagination: {
            type: [Function, Object, Boolean],
            default: undefined
        },
        columns: {
            type: [Array, Function],
            required: true
        },
        tagCols: {
            type: [Array]
        },
        change: {
            type: Function
        },
        showTotal: {
            type: Boolean,
            default: false
        },
        showTop: {
            type: Boolean,
            default: false
        },
    },
    computed: {
        dataSourceHasKey: function () {
            return [...this.dataList]
        },
        scopedSlotsList() {
            let obj = {};
            if (this.tagCols) {
                this.tagCols.forEach(e => {
                    if(e.columnName){
                        obj[e.columnName] = (text, record, index) => {
                            if(!text || record.isEmpty){
                                return ''
                            }
                            if(e.columnValue && e.columnValue[text]){
                                return <a-tag color={text ? e.columnValue[text].color : ''}>{text ? e.columnValue[text].label : ''}</a-tag>
                            }
                            return text
                        }
                    }
                })
            }
            return obj
        },
        paginationHasTotal: {
            get() {
                let arr = this.dataList.filter(e => !e.isEmpty);
                let pagination = this.pagination || {pageSize: 10};
                let totalCnt = pagination.total || arr.length;
                // if (!pagination.pageSizeOptions) {
                //     pagination.pageSizeOptions = ["10", "20", "30", "40"];
                //     pagination.showSizeChanger = true;
                //     if (pagination.pageSize && !pagination.pageSizeOptions.includes(`${pagination.pageSize}`)) {
                //         let index = Math.floor(pagination.pageSize / 10);
                //         pagination.pageSizeOptions.splice(index, 0, `${pagination.pageSize}`);
                //     }
                // }
                return {
                    ...pagination,
                    total: totalCnt || 0,
                    showTotal: (total, range) => totalCnt ? `总记录数：${totalCnt}， 当前页记录数：${range[1] - range[0] + 1}` : ``
                }
            },
            set(val) {
                return val;
            }
        },
    },
    watch: {
        'rowSelection.selectedRowKeys': function (val) {
            this.oldSelection.selectedRowKeys = val.filter(key => {
                let row = this.dataSourceHasKey.find(row => row[this.rowKey] === key)
                if (row) {
                    return !row.isEmpty
                }
            })
        },
        dataSource: function (val) {
            this.updateDataSource(val);
        },
        paginationHasTotal: function (val) {
            //表格使用分页查询时绑定页码
            if ('current' in val && 'current' in this.paginationModel && val.current !== this.paginationModel.current) {
                this.paginationModel.current = val.current;
            }
            this.paginationModel.total = val.total;
            this.paginationModel.showTotal = val.showTotal;
        },
        columns: function (val) {
            this.setColumns(val);
        },
    },
    methods: {
        resize() {
            this.filterOk();
        },
        filterOk() {
            this.columnsView = lodash.cloneDeep(this.columns.filter(e => this.checkedList.includes(e.dataIndex)));
            this.columnsModelView = lodash.cloneDeep(this.columnsModel.filter(e => this.checkedList.includes(e.dataIndex)));
            this.showFilter = false;
            if ('scroll' in this.$attrs && this.$attrs.scroll
                && 'x' in this.$attrs.scroll && typeof this.$attrs.scroll.x === "function") {
                let x = 0;
                this.columnsModelView.forEach(e => {
                    x += e.width
                });
                // this.$attrs.scroll.x = x;
                this.scrollX = x;
                //判断当前窗口宽度
                if (x < window.innerWidth) {
                    this.columnsModelView.forEach(e => {
                        if (e.fixed) {
                            delete e.fixed;
                        }
                    })
                }
                //判断当前表格宽度
                if (x < this.$refs.table1.$el.clientWidth) {
                    this.columnsView.forEach(e => {
                        if (e.fixed) {
                            delete e.fixed;
                        }
                    })
                }
            }
        },
        updateDataSource(val) {
            let result = [...val];
            let offset = 10;
            let length = val.length;
            if (this.paginationModel && this.paginationModel.pageSize) {
                offset = this.paginationModel.pageSize
            }

            let count = 0;

            //不分页判断,根据用户设定的scroll.y值计算填充的空白行数量
            if (this.pagination !== undefined && !this.pagination) {
                if (this.showEditor) {
                    count = length <= offset ? offset - length : 0;
                } else if (this.$attrs.scroll && this.$attrs.scroll.y) {
                    offset = Math.floor(this.$attrs.scroll.y / 41);
                    count = length <= offset ? offset - length : 0 ;
                }
                this.isPagination = false;
            } else {
                count = length <= offset ? offset - length : length % offset === 0 ? 0 : offset - length % offset;
            }

            for (let i = 0; i < count; i++) {
                let temp = {isEmpty: true, lodId: ''}
                this.$set(result, length + i, temp)
            }

            /**
             * 如果没有传入rowKey字段使用默认的key
             * */
            const rowKey = this.rowKey;

            this.dataList = result.map(r => {
                if (rowKey !== 'key') {
                    return r;
                }

                if (!r[rowKey]) {
                    r[rowKey] = uuidv4();
                }
                return r
            });
        },
        setColumns(val) {
            this.columnsModel = lodash.cloneDeep(val);
            this.columnsModelView = lodash.cloneDeep(val);
            this.columnsView = lodash.cloneDeep(val);

            this.plainOptions = this.columnsModel.map(e => {
                return {
                    label: e.title,
                    value: e.dataIndex
                };
            });
            this.checkedList = this.columnsModel.map(e => {
                return e.dataIndex;
            });
            this.checkAll = true;
            this.indeterminate = false;
            let flag = false;

            //判断全屏化时是否保留fixed属性
            if ('scroll' in this.$attrs && this.$attrs.scroll && 'x' in this.$attrs.scroll) {
                let x;
                if (typeof this.$attrs.scroll.x === "function") {
                    x = this.$attrs.scroll.x();
                } else {
                    x = this.$attrs.scroll.x;
                }
                this.scrollX = x;
                if (x < window.innerWidth) {
                    flag = true;
                }
            } else {
                flag = true;
            }
            if (flag) {
                this.columnsModelView.forEach(e => {
                    if (e.fixed) {
                        delete e.fixed;
                    }
                });
            }
        },
        onChange(checkedList) {
            this.indeterminate = !!checkedList.length && checkedList.length < this.plainOptions.length;
            this.checkAll = checkedList.length === this.plainOptions.length;
        },
        onCheckAllChange(e) {
            Object.assign(this, {
                checkedList: e.target.checked ? this.plainOptions.map(e => e.value) : [],
                indeterminate: false,
                checkAll: e.target.checked,
            });
        },
        setPagination(val) {
            this.paginationModel = lodash.cloneDeep(val || {pageSize: 10});
            this.paginationModel.pageSizeOptions = ["10", "17", "20", "30", "40"];
            this.paginationModel.showSizeChanger = true;
        },
    },
    mounted() {
        this.updateDataSource(this.dataSource);
        this.setColumns(this.columns);
        this.setPagination(this.pagination);
    },
    render() {
        let showExport = this.showExport
        const on = {
            ...this.$listeners
        };
        let props = {
            size: "small", //默认small size 可以在父组件中自定义size覆盖
            locale: {emptyText: this.$t('empty')},// 默认的文案, 没有数据的提示
            defaultExpandAllRows: true,//默认展开所有数据
            ...{
                customRow: this.customRow,
                //斑马条纹
                // rowClassName: this.rowClassName,
            },
            ...this.$attrs, ...this.$props,
            rowSelection: {
                ...this.oldSelection,
                getCheckboxProps: (record) => {
                    let oldProp = {};
                    if (this.oldSelection.getCheckboxProps) {
                        oldProp = this.oldSelection.getCheckboxProps(record).props
                    }
                    return {
                        props: {
                            ...oldProp,
                            disabled: record.isEmpty || oldProp.disabled
                        }
                    }
                }
            },
            columns: this.tagCols ? this.columnsView.map(col => {
                    let obj = this.tagCols.find(e => e.columnName === col.dataIndex)
                    if (obj && !col.scopedSlots) {
                        return {
                            ...col,
                            scopedSlots: {customRender: col.dataIndex}
                        }
                    } else {
                        return col
                    }
                }
            ) : this.columnsView,
            dataSource: this.dataSourceHasKey,
            pagination: this.paginationHasTotal
        };
        if (!this.selection) {
            props = {...props, rowSelection: undefined}
        }
        //单页行数过多时,设置表格y轴滑动
        let scroll = {};
        if ('scroll' in props && props.scroll) {
            scroll = {...props.scroll, x: this.scrollX || null};
        }
        //当未设置y时,赋予默认值
        if (!('y' in scroll)) {
            props = {...props, scroll: {...scroll}};
        }
        let propsModel = {
            ...props,
            columns: this.columnsModelView,
            pagination: this.paginationModel,
            scroll: {...scroll, y: 715}
        };
        if (!this.isPagination) {
            props.pagination = false;
            propsModel.pagination = false;
        }
        // slots循环
        const slots = Object.keys(this.$slots).map(slot => {
            return (
                <template
                    slot={slot}> {this.$slots[slot]}
                </template>)
        });
        let span = "0.5";
        let header = (
            <template
                slot="title">
                <a-row type="flex" justify="end">
                    <a-col flex='25px' style={{display: showExport ? 'block' : 'none'}}>
                        <a-tooltip>
                            <template slot="title">
                                导出
                            </template>
                            <icon-export isFollowTheme={true} events={this.exportExcel}></icon-export>
                        </a-tooltip>
                    </a-col>
                    <a-col flex='25px'>
                        <a-tooltip>
                            <template slot="title">
                                列过滤
                            </template>
                            <icon-filter isFollowTheme={true} events={this.showFilterModel}/>
                        </a-tooltip>
                    </a-col>
                    <a-col flex='15px'>
                        <a-tooltip>
                            <template slot="title">
                                全屏化
                            </template>
                            <icon-fullscreen isFollowTheme={true} events={this.showModel}/>
                        </a-tooltip>
                    </a-col>
                </a-row>
            </template>
        )
        let headerModel = (
            <template
                slot="title">
                <a-row type="flex" justify="end">
                    <a-col flex='25px' style={{display: showExport ? 'block' : 'none'}}>
                        <a-tooltip getPopupContainer={() => document.getElementById("fullModel")}>
                            <template slot="title">
                                导出
                            </template>
                            <icon-export isFollowTheme={true} events={this.exportExcel}/>
                        </a-tooltip>
                    </a-col>
                    <a-col flex='15px'>
                        <a-tooltip getPopupContainer={() => document.getElementById("fullModel")}>
                            <template slot="title">
                                列过滤
                            </template>
                            <icon-filter isFollowTheme={true} events={this.showFilterModel}/>
                        </a-tooltip>
                    </a-col>
                </a-row>
            </template>
        )
        if (!this.showTop) {
            header = '';
            headerModel = '';
        }
        const table = (
            <a-table
                v-resize={this.resize}
                ref="table1"
                bordered
                props={props}
                scopedSlots={{...this.$scopedSlots, ...this.scopedSlotsList}}
                on={on}>
                {slots}
                {header}
            </a-table>);
        const modelTable = (
            <a-table
                id="fullModel"
                style="margin-top: 35px"
                bordered
                props={propsModel}
                scopedSlots={{...this.$scopedSlots, ...this.scopedSlotsList}}
                on={on}>
                {slots}
                {headerModel}
            </a-table>);

        const model = (
            <a-modal visible={this.showEditor} class="testModel" width="100%" height="100%" centered zIndex={1700}
                     footer={null} oncancel={this.closeModel} destroyOnClose={true}>
                {modelTable}
            </a-modal>);

        const filterModel = (
            <a-modal visible={this.showFilter} class="filterModel" width="700px" centered zIndex={1900}
                     onok={this.filterOk} oncancel={this.closeFilterModel} destroyOnClose={true}>
                <div>
                    <div style={{borderBottom: '1px solid #E9E9E9'}}>
                        <a-checkbox indeterminate={this.indeterminate} checked={this.checkAll}
                                    onChange={this.onCheckAllChange}>
                            全选
                        </a-checkbox>
                    </div>
                    <br/>
                    <a-checkbox-group v-model={this.checkedList} options={this.plainOptions} onChange={this.onChange}/>
                </div>
            </a-modal>
        );

        return (<div class="m-table">
            {table}
            {model}
            {filterModel}
        < /div>);

    },
}
</script>

<style>
.testModel .ant-modal-body {
    height: 100vh;
    overflow: auto;
    /*position:relative;*/
}

.filterModel .ant-checkbox-wrapper {
    width: 155px;
}

/*.testModel .ant-table-wrapper {*/
/*    position:absolute;*/
/*    !*transform:translateX(-50%) translateY(-50%);*!*/
/*    -webkit-transform:translateX(-50%) translateY(-50%);*/
/*}*/

</style>

